package weather.language.extractor;

import java.util.*;

import weather.language.*;
import weather.util.*;

public class SiteExtractor
{
	public void extract(String sentence)
	{
		Map<String, Site> varToSite = new HashMap<String, Site>();
		Map<String, String> varToUserSite = new HashMap<String, String>();
		
		StringBuffer sentenceWithVars = new StringBuffer(sentence);
		
		int varNum = 0;
		int i;
		
		boolean siteExtracted;
		do
		{
			siteExtracted = false;
			for (String siteName: allNamesToSitesMap.keySet())
				while ((i = clean(new String(sentenceWithVars)).indexOf(
						clean(siteName))) != -1)
				{	
					siteExtracted = true;
					
					String var = "$(site_" + varNum++ + ")";
					sentenceWithVars = sentenceWithVars.replace(i, i + siteName.length(), var);
					varToSite.put(var, allNamesToSitesMap.get(siteName));
					varToUserSite.put(var, siteName);
				}
		}
		while (siteExtracted);
		
		this.sentenceWithVars = new String(sentenceWithVars);
		this.varToSite = varToSite;
		this.varToUserSite = varToUserSite;
	}

	public String getSentenceWithVars()
	{
		return sentenceWithVars;
	}

	public Map<String, Site> getVarToSite()
	{
		return varToSite;
	}

	public Map<String, String> getVarToUsedSiteName()
	{
		return varToUserSite;
	}
	
	public void loadKnownSitesSet(Set<Site> knownSitesSet)
	{
		allNamesToSitesMap.clear();
		for (Site site: knownSitesSet)
		{
			this.knownSitesSet.add(site);
			for (String name: site.getAllNames())
				allNamesToSitesMap.put(name, site);
		}
	}

	private String clean(String siteName)
	{
		return Strings.cleanPolishDiactricalSigns(siteName.toLowerCase());
	}
	
	private String sentenceWithVars;
	private Map<String, Site> varToSite;
	private Map<String, String> varToUserSite;
	
	private Map<String, Site> allNamesToSitesMap = new TreeMap<String, Site>(new StringLengthComparator());
	private Set<Site> knownSitesSet = new HashSet<Site>();
	
	private static class StringLengthComparator implements Comparator<String>
	{
		@Override
		public int compare(String s1, String s2)
		{
			int lendiff = s1.length() - s2.length();
			
			if (lendiff < 0)
				return 1;
			else if (lendiff > 0)
				return -1;
			else
				return s1.compareTo(s2);
		}
	}
	
	public static class Tester
	{
		public static void main(String[] args)
		{
			SiteExtractor se = new SiteExtractor();
			String sentence = "Today in ROMa won't rain. Tomorrow in Wa-wa and rome will rain.";
			
			se.loadKnownSitesSet(prepareKnownSitesSet());
			
			se.extract(sentence);
			
			System.out.println(sentence);
			System.out.println(se.getSentenceWithVars());
			System.out.println(se.getVarToUsedSiteName());
			System.out.println(se.getVarToSite());
		}

		private static Set<Site> prepareKnownSitesSet()
		{
			Set<Site> knownSitesSet = new HashSet<Site>();
			Set<String> otherNames = new HashSet<String>();
			
			knownSitesSet.add(new Site("Berlin"));
			knownSitesSet.add(new Site("New York"));
			knownSitesSet.add(new Site("Paris"));
			
			otherNames.add("Warszawa");
			otherNames.add("Wa-wa");
			knownSitesSet.add(new Site("Warsaw", otherNames));
			knownSitesSet.add(new Site("Sankt Petersburg"));
			
			otherNames.clear();
			otherNames.add("Roma");
			knownSitesSet.add(new Site("Rome", otherNames));
			knownSitesSet.add(new Site("Vienna"));
			knownSitesSet.add(new Site("Brussels"));
			
			return knownSitesSet;
		}
	}
}
